<script setup lang="ts">
import { inject, onMounted, onUnmounted, reactive, ref, watch } from 'vue';

import { ElCheck, ElClose } from '@vben/icons';

import {
  ElCol,
  ElCollapse,
  ElCollapseItem,
  ElInput,
  ElInputNumber,
  ElOption,
  ElRadio,
  ElRadioGroup,
  ElRow,
  ElSelect,
  ElSlider,
  ElSwitch,
} from 'element-plus';

import { vectorServiceApi } from '#/api';
import { usePublicStore, useSceneStore } from '#/store';

const emits = defineEmits(['confirmBtnAvalible']);
const publicStore = usePublicStore();
const sceneStore = useSceneStore();
const currentLayer = inject('currentSelectedLayer') as any;
const activeNames = ref(['textProperty']);
const fieldList = ref<Array<any>>(); // 当前图层的字段列表
const field = ref('');
const isOpen = ref(false);
const currentSource = ref();
const selectedLayer = inject('currentSelectedLayer') as any;
const emptyText = ref('该数据不含字段');

const textLabelOptions = reactive({
  layer: selectedLayer.value,
  renderField: field,
  isOpen,
  layout: {
    visibility: 'visible',
    'text-field': [],
    'text-font': ['Open Sans Semibold'],
    'text-size': 14,
    'text-allow-overlap': false, // 允许压盖(用于解决符号与其他图层中符号重叠的问题，例如icon和text，为true时允许符号重叠)
    'text-ignore-placement': false, // 忽略图标位置(用于解决当前图层内不同符号在不同缩放视角下碰撞冲突时的显示问题，为true时允许符号碰撞)
    'text-anchor': 'center', // 文本锚定位置
    'text-justify': 'center', // 文字水平对齐方式
    'text-offset': [0, 0], // 文字偏移
    'text-rotate': 0, // 文字旋转角度
    'text-transform': 'none', // 文字转换(全部大写、全部小写、无转换)
    'text-writing-mode': ['horizontal'], // 文本排列方式
    'symbol-placement': 'point',
    'symbol-spacing': 250, // 图标间隔（最小为1，默认为250）
  } as any,
  paint: {
    'text-color': 'rgb(0,0,0)',
    'text-halo-color': '#FFD700', // 文字光晕颜色
    'text-halo-blur': 0, // 文字光晕模糊度
    'text-halo-width': 0, // 文字光晕宽度,不超过字体大小的1/4
    'text-opacity': 100, // 文字透明度
  } as any,
  // mapLayer: {} as any
});

const textAnchorList = ref<Array<string>>([
  'center',
  'left',
  'right',
  'top',
  'bottom',
  'top-left',
  'top-right',
  'bottom-left',
  'bottom-right',
]);

const fonts = ref<Array<string>>([
  'Open Sans Bold',
  'Open Sans Bold Italic',
  'Open Sans Condensed Bold',
  'Open Sans Condensed Light',
  'Open Sans Condensed Light Italic',
  'Open Sans Extra Bold',
  'Open Sans Extra Bold Italic',
  'Open Sans Italic',
  'Open Sans Light',
  'Open Sans Light Italic',
  'Open Sans Regular',
  'Open Sans Semibold',
  'Open Sans Semibold Italic',
  'PT Sans Bold',
  'PT Sans Bold Italic',
  'PT Sans Caption Regular',
  'PT Sans Caption Web Bold',
  'PT Sans Italic',
  'PT Sans Narrow Bold',
  'PT Sans Narrow Regular',
  'PT Sans Regular',
  'Roboto Black',
  'Roboto Black Italic',
  'Roboto Bold',
  'Roboto Bold Italic',
  'Roboto Condensed Bold',
  'Roboto Condensed Bold Italic',
  'Roboto Condensed Italic',
  'Roboto Condensed Light',
  'Roboto Condensed Light Italic',
  'Roboto Condensed Regular',
  'Roboto Italic',
  'Roboto Light',
  'Roboto Light Italic',
  'Roboto Medium',
  'Roboto Medium Italic',
  'Roboto Regular',
  'Roboto Thin',
  'Roboto Thin Italic',
  'Times New Roman',
  'Times New Roman Bold',
  'Times New Roman Bold Italic',
  'Times New Roman Italic',
  '仿宋',
  '宋体',
  '宋体 加粗',
  '微软雅黑',
  '微软雅黑 加粗',
  '微软雅黑 加粗 斜体',
  '楷体',
  '等线',
  '等线 加粗',
  '黑体',
]);

const renderParamsReturn = () => {
  const renderParams = currentLayer.value.labelLayer;
  field.value = renderParams.layout['text-field'][1];
  isOpen.value = renderParams.layout.visibility === 'visible';

  Object.keys(renderParams.layout).forEach((key: string) => {
    if (!['text-field', 'visibility'].includes(key)) {
      textLabelOptions.layout[key] = renderParams.layout[key];
    }
  });
  Object.keys(renderParams.paint).forEach((key: string) => {
    textLabelOptions.paint[key] =
      key === 'text-opacity'
        ? renderParams.paint[key] * 100
        : renderParams.paint[key];
  });
};
const getSource = () => {
  sceneStore.currentSceneConfig.sources.forEach((item: any) => {
    if (item.sourceId === currentLayer.value.source) {
      currentSource.value = item;
    }
  });
};
// 请求当前图层字段值
const requestFields = async () => {
  fieldList.value = await (currentSource.value.sourceType === 'vector'
    ? vectorServiceApi.getFields(currentLayer.value['source-layer'])
    : vectorServiceApi.getFieldsFromGeojson(currentLayer.value.source));
};

const handleOpenChange = (val: boolean | number | string | undefined) => {
  if (val) emits('confirmBtnAvalible', val);
};
watch(
  textLabelOptions,
  () => {
    publicStore.setLabelOptions(textLabelOptions);
  },
  {
    immediate: true,
    deep: true,
  },
);
watch(isOpen, () => {
  if (!isOpen.value) {
    textLabelOptions.layout.visibility = 'none';
  }
});
onMounted(() => {
  if (currentLayer.value.labelLayer) {
    renderParamsReturn();
  } else {
    if (currentLayer.value.type === 'line') {
      textLabelOptions.layout['symbol-placement'] = 'line';
    }
  }
  if (!isOpen.value) {
    emits('confirmBtnAvalible', false);
  }
  getSource();
  requestFields(); // 请求字段
});
onUnmounted(() => {
  emits('confirmBtnAvalible', true);
});
</script>

<template>
  <div class="all">
    <ElRow class="itemRow">
      <ElCol :span="8">
        <span class="label-style" style="font-weight: 700; line-height: 40px">
          是否开启文字注记：
        </span>
      </ElCol>
      <ElCol :span="16">
        <div>
          <ElRadioGroup
            v-model="isOpen"
            @change="handleOpenChange"
            size="large"
          >
            <ElRadio :label="true">是</ElRadio>
            <ElRadio :label="false">否</ElRadio>
          </ElRadioGroup>
        </div>
      </ElCol>
    </ElRow>
    <ElRow class="itemRow">
      <ElCol :span="4">
        <span class="label-style"> 标注字段： </span>
      </ElCol>
      <ElCol :span="20">
        <ElSelect
          size="small"
          v-model="field"
          placeholder="选择标注字段"
          style="width: 100%"
          :no-data-text="emptyText"
          :disabled="!isOpen"
        >
          <ElOption
            v-for="item in fieldList"
            :key="item"
            :label="item"
            :value="item"
          />
        </ElSelect>
      </ElCol>
    </ElRow>
    <ElCollapse v-model="activeNames" accordion>
      <ElCollapseItem title="文本属性" name="textProperty">
        <ElRow class="itemRow">
          <ElCol :span="4">
            <span class="label-style"> 字体： </span>
          </ElCol>
          <ElCol :span="20">
            <ElSelect
              size="small"
              v-model="textLabelOptions.layout['text-font'][0]"
              placeholder="请选择字体"
              style="width: 100%"
              :disabled="!isOpen"
            >
              <ElOption
                v-for="font in fonts"
                :key="font"
                :label="font"
                :value="font"
              />
            </ElSelect>
          </ElCol>
        </ElRow>
        <ElRow class="itemRow">
          <ElCol :span="4">
            <span class="label-style"> 字体大小： </span>
          </ElCol>
          <ElCol :span="20">
            <ElInput
              v-model.number="textLabelOptions.layout['text-size']"
              placeholder="Please input"
              :disabled="!isOpen"
              size="small"
            >
              <template #append>像素</template>
            </ElInput>
          </ElCol>
        </ElRow>
        <ElRow class="itemRow">
          <ElCol :span="4">
            <span class="label-style"> 字体颜色： </span>
          </ElCol>
          <ElCol :span="20">
            <ElInput
              class="colorInput"
              v-model="textLabelOptions.paint['text-color']"
              type="color"
              :disabled="!isOpen"
              size="small"
            />
          </ElCol>
        </ElRow>
        <ElRow class="itemRow">
          <ElCol :span="6">
            <span class="label-style"> 文字模式： </span>
          </ElCol>
          <ElCol :span="18">
            <div>
              <ElRadioGroup
                v-model="textLabelOptions.layout['text-transform']"
                :disabled="!isOpen"
              >
                <ElRadio label="uppercase" size="small">全部大写</ElRadio>
                <ElRadio label="lowercase" size="small">全部小写</ElRadio>
                <ElRadio label="none" size="small">无</ElRadio>
              </ElRadioGroup>
            </div>
          </ElCol>
        </ElRow>
        <ElRow class="itemRow">
          <ElCol :span="4">
            <span class="label-style"> 不透明度： </span>
          </ElCol>
          <ElCol :span="20">
            <ElSlider
              v-model.number="textLabelOptions.paint['text-opacity']"
              show-input
              :disabled="!isOpen"
              size="small"
            />
          </ElCol>
        </ElRow>
      </ElCollapseItem>
      <ElCollapseItem title="位置属性" name="locationProperty">
        <ElRow class="itemRow">
          <ElCol :span="4" style="display: flex; align-items: center">
            <span class="label-style"> 允许压盖： </span>
          </ElCol>
          <ElCol :span="4">
            <ElSwitch
              v-model="textLabelOptions.layout['text-allow-overlap']"
              inline-prompt
              :active-icon="ElCheck"
              :inactive-icon="ElClose"
              size="default"
              :disabled="!isOpen"
            />
          </ElCol>
          <ElCol :span="4" style="display: flex; align-items: center">
            <span class="label-style"> 忽略放置： </span>
          </ElCol>
          <ElCol :span="4">
            <ElSwitch
              v-model="textLabelOptions.layout['text-ignore-placement']"
              inline-prompt
              :active-icon="ElCheck"
              :inactive-icon="ElClose"
              size="default"
              :disabled="!isOpen"
            />
          </ElCol>
        </ElRow>
        <ElRow
          class="itemRow"
          v-if="['line', 'fill'].includes(selectedLayer.type)"
        >
          <ElCol :span="4">
            <span class="label-style"> 放置规则： </span>
          </ElCol>
          <ElCol :span="10" style="padding-top: 2px">
            <div>
              <ElRadioGroup
                v-model="textLabelOptions.layout['symbol-placement']"
                :disabled="!isOpen"
              >
                <ElRadio label="point" size="small">点</ElRadio>
                <ElRadio label="line" size="small">沿线</ElRadio>
                <ElRadio label="line-center" size="small">线中心</ElRadio>
              </ElRadioGroup>
            </div>
          </ElCol>
          <ElCol
            :span="3"
            :offset="1"
            v-if="textLabelOptions.layout['symbol-placement'] === 'line'"
          >
            <span class="label-style" style="padding-top: 2px"> 间隔： </span>
          </ElCol>
          <ElCol
            :span="6"
            class="define-input-number"
            v-if="textLabelOptions.layout['symbol-placement'] === 'line'"
          >
            <ElInputNumber
              v-model="textLabelOptions.layout['symbol-spacing']"
              :min="1"
              :step="10"
              controls-position="right"
              :disabled="!isOpen"
              size="small"
            />
            <div class="define-append">px</div>
          </ElCol>
        </ElRow>
        <ElRow class="itemRow">
          <ElCol :span="4">
            <span class="label-style"> 锚定位置： </span>
          </ElCol>
          <ElCol :span="20">
            <ElSelect
              size="small"
              v-model="textLabelOptions.layout['text-anchor']"
              placeholder="选择文本锚定位置"
              style="width: 100%"
              :disabled="!isOpen"
            >
              <ElOption
                v-for="item in textAnchorList"
                :key="item"
                :label="item"
                :value="item"
              />
            </ElSelect>
          </ElCol>
        </ElRow>
        <ElRow class="itemRow">
          <ElCol :span="6">
            <span class="label-style"> 文字排列方式： </span>
          </ElCol>
          <ElCol :span="6">
            <div>
              <ElRadioGroup
                v-model="textLabelOptions.layout['text-writing-mode'][0]"
                :disabled="!isOpen"
              >
                <ElRadio label="horizontal" size="small">水平</ElRadio>
                <ElRadio label="vertical" size="small">垂直</ElRadio>
              </ElRadioGroup>
            </div>
          </ElCol>
        </ElRow>
        <ElRow class="itemRow">
          <ElCol :span="4">
            <span class="label-style"> 文本对齐： </span>
          </ElCol>
          <ElCol :span="20">
            <div>
              <ElRadioGroup
                v-model="textLabelOptions.layout['text-justify']"
                :disabled="!isOpen"
              >
                <ElRadio label="auto" size="small">自动</ElRadio>
                <ElRadio label="center" size="small">居中</ElRadio>
                <ElRadio label="left" size="small">左对齐</ElRadio>
                <ElRadio label="right" size="small">右对齐</ElRadio>
              </ElRadioGroup>
            </div>
          </ElCol>
        </ElRow>
        <ElRow class="itemRow">
          <ElCol :span="4">
            <span class="label-style" style="padding-top: 2px">
              文本偏移：
            </span>
          </ElCol>
          <ElCol :span="2" style="padding-top: 2px">
            <span> X： </span>
          </ElCol>
          <ElCol :span="7">
            <ElInput
              v-model.number="textLabelOptions.layout['text-offset'][0]"
              placeholder="请输入X向偏移"
              :disabled="!isOpen"
              size="small"
            />
          </ElCol>
          <ElCol :span="2" :offset="2" style="padding-top: 2px">
            <span> Y： </span>
          </ElCol>
          <ElCol :span="7">
            <ElInput
              v-model.number="textLabelOptions.layout['text-offset'][1]"
              placeholder="请输入Y向偏移"
              :disabled="!isOpen"
              size="small"
            />
          </ElCol>
        </ElRow>
        <ElRow class="itemRow">
          <ElCol :span="4">
            <span class="label-style" style="padding-top: 2px">
              文字旋转：
            </span>
          </ElCol>
          <ElCol :span="20" style="padding-top: 2px">
            <ElInput
              v-model.number="textLabelOptions.layout['text-rotate']"
              placeholder="Please input"
              :disabled="!isOpen"
              size="small"
            >
              <template #append>度</template>
            </ElInput>
          </ElCol>
        </ElRow>
      </ElCollapseItem>
    </ElCollapse>
    <ElCollapse v-model="activeNames" accordion>
      <ElCollapseItem title="文字光晕" name="otherStyle">
        <ElRow class="itemRow">
          <ElCol :span="5">
            <span class="label-style"> 光晕模糊度： </span>
          </ElCol>
          <ElCol :span="19">
            <ElSlider
              v-model.number="textLabelOptions.paint['text-halo-blur']"
              show-input
              :max="30"
              :disabled="!isOpen"
              size="small"
            />
          </ElCol>
        </ElRow>
        <ElRow class="itemRow">
          <ElCol :span="4">
            <span class="label-style"> 光晕颜色： </span>
          </ElCol>
          <ElCol :span="20">
            <ElInput
              v-model="textLabelOptions.paint['text-halo-color']"
              type="color"
              :disabled="!isOpen"
              size="small"
            />
          </ElCol>
        </ElRow>
        <ElRow class="itemRow">
          <ElCol :span="4">
            <span class="label-style"> 光晕宽度： </span>
          </ElCol>
          <ElCol :span="20">
            <ElInput
              v-model.number="textLabelOptions.paint['text-halo-width']"
              placeholder="Please input"
              :disabled="!isOpen"
              size="small"
            >
              <template #append>像素</template>
            </ElInput>
          </ElCol>
        </ElRow>
      </ElCollapseItem>
    </ElCollapse>
  </div>
</template>

<style lang="scss" scoped>
.all {
  width: 100%;
}

.itemRow {
  width: 100%;
  padding: 5px;
}

.el-input {
  width: 100%;
}

.label-style {
  font-size: 15px;
}

.colorInput {
  caret-color: transparent;
}

:deep(.colorInput .el-input__inner:hover) {
  cursor: pointer;
}

:deep(.el-table .el-table__cell) {
  text-align: center;
}

.legend {
  margin-top: 2px;
}

:deep(.el-table:not(.el-table--border) .el-table__cell) {
  border: none;

  /* 去除表格边框 */
}

:deep(.el-table--small .cell) {
  height: 25px;
}

:deep(.el-collapse-item__header) {
  font-size: 15px;
  font-weight: 600;
}

.keep-layer {
  display: flex;
  align-items: center;
  justify-content: left;
}

:deep(.el-alert) {
  --el-alert-padding: 8px 0px;

  padding: var(--el-alert-padding);
}

/* 自定义数字输入框append  */
.define-input-number {
  display: flex;
  width: 100%;
  border: 1px solid #dcdfe6;
  border-radius: 8px;

  .el-input-number--mini {
    flex: 1;
  }

  :deep(.el-input__inner) {
    border: none !important;
  }
}

.define-append {
  display: inline-block;
  width: 40px;
  height: 26px;
  padding: 0 3px;
  font-size: 12px;
  line-height: 26px;
  color: #909399;
  text-align: center;
  background: #f5f7fa;
  border-left: none;
}
</style>
